package cs236369.webserver;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class WebServer {
	
   private ServerSocket mServerSocket;
   private ThreadPoolExecutor mSocketReaderPool;
   private IWebServerConfig mConfig;
   private ThreadPoolExecutor mRequestHandlerPool;
   public WebServer(InputStream config) throws Exception {
		mConfig = new WebServerConfig(config); 
		mSocketReaderPool = new ThreadPoolExecutor(mConfig.getNumSocketReaders(), 
												   mConfig.getNumSocketReaders(), 
				                                   5, TimeUnit.SECONDS, 
				                                   new ArrayBlockingQueue<Runnable>(mConfig.getSocketQueueSize()) );
		mServerSocket = new ServerSocket(mConfig.getPort());
		mRequestHandlerPool = new ThreadPoolExecutor(mConfig.getNumRequestHandlers(), 
				                                     mConfig.getNumRequestHandlers(), 
				                                     5, TimeUnit.SECONDS, 
				                                     new ArrayBlockingQueue<Runnable>(mConfig.getRequestQueueSize()) );
		mConfig.getTypeHandlers();
	}
	
	
	public void init() throws IOException {
		
	}
	
	public void start() {
		for (;;) {
			Socket s = null;
			try {
				s = mServerSocket.accept();
				s.setSoTimeout(50);
				mSocketReaderPool.execute(new SocketReader(s, mConfig, mRequestHandlerPool));
			} catch (IOException e) {
				System.err.println("ERROR: " + e.getMessage());
				e.printStackTrace();
			} catch (RejectedExecutionException e) {
				String res = "HTTP/1.1 503 Service Unavailable\r\n" +
				             "Content-Type: text/html\r\n" +
				             "Content-Length: 27\r\n" +
				             "\r\n" + 
				             "The service is unavailable.";
				try {
					s.getOutputStream().write(res.getBytes());
					s.getOutputStream().flush();	
					s.close();
				} catch (IOException e1) {
					System.err.println("ERROR: Cannot send Service Unavailable client " + e1.getMessage());
					e.printStackTrace();
				}
				
								
			}
			
	    }

	}
	
	public static void main(String[] args) throws Exception {
		WebServer srv = new WebServer(new FileInputStream("config.xml"));
		srv.init();
		srv.start();
	}
}
